home *** CD-ROM | disk | FTP | other *** search
/ Aminet 28 / Aminet 28 (1998)(GTI - Schatztruhe)[!][Dec 1998].iso / Aminet / dev / src / GLperf3.12-src.lha / GLperf / Image.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-09-18  |  15.9 KB  |  538 lines

  1. /*
  2.  * (c) Copyright 1995, Silicon Graphics, Inc.
  3.  * ALL RIGHTS RESERVED
  4.  * Permission to use, copy, modify, and distribute this software for
  5.  * any purpose and without fee is hereby granted, provided that the above
  6.  * copyright notice appear in all copies and that both the copyright notice
  7.  * and this permission notice appear in supporting documentation, and that
  8.  * the name of Silicon Graphics, Inc. not be used in advertising
  9.  * or publicity pertaining to distribution of the software without specific,
  10.  * written prior permission.
  11.  *
  12.  * THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU "AS-IS"
  13.  * AND WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR OTHERWISE,
  14.  * INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY OR
  15.  * FITNESS FOR A PARTICULAR PURPOSE.  IN NO EVENT SHALL SILICON
  16.  * GRAPHICS, INC.  BE LIABLE TO YOU OR ANYONE ELSE FOR ANY DIRECT,
  17.  * SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY
  18.  * KIND, OR ANY DAMAGES WHATSOEVER, INCLUDING WITHOUT LIMITATION,
  19.  * LOSS OF PROFIT, LOSS OF USE, SAVINGS OR REVENUE, OR THE CLAIMS OF
  20.  * THIRD PARTIES, WHETHER OR NOT SILICON GRAPHICS, INC.  HAS BEEN
  21.  * ADVISED OF THE POSSIBILITY OF SUCH LOSS, HOWEVER CAUSED AND ON
  22.  * ANY THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE
  23.  * POSSESSION, USE OR PERFORMANCE OF THIS SOFTWARE.
  24.  *
  25.  * US Government Users Restricted Rights
  26.  * Use, duplication, or disclosure by the Government is subject to
  27.  * restrictions set forth in FAR 52.227.19(c)(2) or subparagraph
  28.  * (c)(1)(ii) of the Rights in Technical Data and Computer Software
  29.  * clause at DFARS 252.227-7013 and/or in similar or successor
  30.  * clauses in the FAR or the DOD or NASA FAR Supplement.
  31.  * Unpublished-- rights reserved under the copyright laws of the
  32.  * United States.  Contractor/manufacturer is Silicon Graphics,
  33.  * Inc., 2011 N.  Shoreline Blvd., Mountain View, CA 94039-7311.
  34.  *
  35.  * Author: John Spitzer, SGI Applied Engineering
  36.  *
  37.  */
  38. #include "Image.h"
  39. #ifdef WIN32 
  40. #include <windows.h>
  41. #include <gl\glaux.h>
  42. #elif __amigaos__
  43. #include <gl/glaux.h>
  44. #else
  45. #include "aux.h"
  46. #endif
  47. #include <math.h>
  48.  
  49. void new_Image(ImagePtr this)
  50. {
  51. }
  52.  
  53. void delete_Image(ImagePtr this)
  54. {
  55. }
  56.  
  57. int Image__SetState(ImagePtr this)
  58. {
  59.     glPixelStorei(GL_UNPACK_SWAP_BYTES, this->imageSwapBytes);
  60.     glPixelStorei(GL_PACK_SWAP_BYTES, this->imageSwapBytes);
  61.     glPixelStorei(GL_UNPACK_LSB_FIRST, this->imageLSBFirst);
  62.     glPixelStorei(GL_PACK_LSB_FIRST, this->imageLSBFirst);
  63.     glPixelStorei(GL_UNPACK_ALIGNMENT, this->imageAlignment);
  64.     glPixelStorei(GL_PACK_ALIGNMENT, this->imageAlignment);
  65.     return 0;
  66. }
  67.  
  68. static GLfloat Clamp0to1(const GLfloat x)
  69. {
  70.     return (fabs(x) - fabs(x-1.)) * .5 + .5;
  71. }
  72.  
  73. static GLfloat CalcComp(const GLfloat x, const GLfloat y, const int comp)
  74. {
  75.     switch (comp) {
  76.         case 0: 
  77.             return Clamp0to1((1.0 - x) * (1.0 - x) + (1.0 - y) * (1.0 - y) * 1.2);
  78.         case 1:
  79.             return Clamp0to1((2.0 * x * (1.0 - x) + 2.0 * y * (1.0 - y)) * 1.2);
  80.         case 2:
  81.             return Clamp0to1((x * x + y * y) * 1.2);
  82.         case 3:
  83.             return Clamp0to1((x + y)/2.);
  84.     }
  85. }
  86.  
  87. void* new_ImageData(int width, int height, int format, int type, int alignment, int swapBytes, int lsbFirst, int memAlign, int *size)
  88. {
  89.     /* Intermediate variables */
  90.     int iwidth;  /* image width, including alignment padding and borders  */
  91.     int iheight; /* image height, including alignment padding and borders */
  92.     void *image; /* image data                                            */
  93.     int imageSize;
  94.     int comps;   /* number of components in image                         */
  95.     unsigned int order;   /* order of components in image                 */
  96.  
  97.     switch (format) {
  98.     case GL_COLOR_INDEX:
  99.     case GL_STENCIL_INDEX:
  100.     case GL_DEPTH_COMPONENT:
  101.     case GL_RED:
  102.     case GL_LUMINANCE:
  103.         order = 0x0000;
  104.         comps = 1;
  105.         break;
  106.     case GL_GREEN:
  107.         order = 0x1000;
  108.         comps = 1;
  109.         break;
  110.     case GL_BLUE:
  111.         order = 0x2000;
  112.         comps = 1;
  113.         break;
  114.     case GL_ALPHA:
  115.         order = 0x3000;
  116.         comps = 1;
  117.         break;
  118.     case GL_LUMINANCE_ALPHA:
  119.         order = 0x0100;
  120.         comps = 2;
  121.         break;
  122.     case GL_RGB:
  123.         order = 0x0120;
  124.         comps = 3;
  125.         break;
  126.     case GL_RGBA:
  127.         order = 0x0123;
  128.         comps = 4;
  129.         break;
  130. #ifdef GL_EXT_abgr
  131.     case GL_ABGR_EXT:
  132.         order = 0x3210;
  133.         comps = 4;
  134.         break;
  135. #endif
  136.         break;
  137.     }
  138.  
  139.     if (type == GL_BITMAP) {
  140.     /* Move from bits to bytes */
  141.     iwidth = (width + 7)/8;
  142.     } else {
  143.     iwidth = width;
  144.     }
  145.  
  146.     iheight = height;
  147.  
  148.     switch (type) {
  149.     case GL_BITMAP:
  150.         #include "ImgBitmp.c"
  151.         break;
  152.     case GL_UNSIGNED_BYTE:
  153.             #define TYPE GLubyte
  154.             #define CONVERT(x) (255. * x)
  155.             #include "ImgSimp.c"
  156.             #undef TYPE
  157.             #undef CONVERT
  158.             break;
  159.     case GL_BYTE:
  160.             #define TYPE GLbyte
  161.             #define CONVERT(x) (255. * x -1.)/2.
  162.             #include "ImgSimp.c"
  163.             #undef TYPE
  164.             #undef CONVERT
  165.             break;
  166.         case GL_UNSIGNED_SHORT:
  167.             #define TYPE GLushort
  168.             #define CONVERT(x) (65535. * x)
  169.             #include "ImgSimp.c"
  170.             #undef TYPE
  171.             #undef CONVERT
  172.             break;
  173.         case GL_SHORT:
  174.             #define TYPE GLshort
  175.             #define CONVERT(x) (65535. * x - 1.)/2.
  176.             #include "ImgSimp.c"
  177.             #undef TYPE
  178.             #undef CONVERT
  179.             break;
  180.         case GL_UNSIGNED_INT:
  181.             #define TYPE GLuint
  182.             #define CONVERT(x) (4294967295. * x)
  183.             #include "ImgSimp.c"
  184.             #undef TYPE
  185.             #undef CONVERT
  186.             break;
  187.         case GL_INT:
  188.             #define TYPE GLint
  189.             #define CONVERT(x) (4294967295. * x - 1.)/2.
  190.             #include "ImgSimp.c"
  191.             #undef TYPE
  192.             #undef CONVERT
  193.             break;
  194.         case GL_FLOAT:
  195.             #define TYPE GLfloat
  196.             #define CONVERT(x) (x)
  197.             #include "ImgSimp.c"
  198.             #undef TYPE
  199.             #undef CONVERT
  200.             break;
  201. #ifdef GL_EXT_packed_pixels
  202.     case GL_UNSIGNED_BYTE_3_3_2_EXT:
  203.             #define TYPE GLubyte
  204.             #define RED_MASK   0xe0
  205.             #define GREEN_MASK 0x1c
  206.             #define BLUE_MASK  0x03
  207.             #define ALPHA_MASK 0x00
  208.         #define RED_SHIFT   24
  209.         #define GREEN_SHIFT 27
  210.         #define BLUE_SHIFT  30
  211.         #define ALPHA_SHIFT 0
  212.             #include "ImgPack.c"
  213.             #undef TYPE
  214.             #undef RED_MASK
  215.             #undef GREEN_MASK
  216.             #undef BLUE_MASK
  217.             #undef ALPHA_MASK
  218.         #undef RED_SHIFT
  219.         #undef GREEN_SHIFT
  220.         #undef BLUE_SHIFT
  221.         #undef ALPHA_SHIFT
  222.             break;
  223.     case GL_UNSIGNED_SHORT_4_4_4_4_EXT:
  224.             #define TYPE GLushort
  225.             #define RED_MASK   0xf000
  226.             #define GREEN_MASK 0x0f00
  227.             #define BLUE_MASK  0x00f0
  228.             #define ALPHA_MASK 0x000f
  229.         #define RED_SHIFT   16
  230.         #define GREEN_SHIFT 20
  231.         #define BLUE_SHIFT  24
  232.         #define ALPHA_SHIFT 28
  233.             #include "ImgPack.c"
  234.             #undef TYPE
  235.             #undef RED_MASK
  236.             #undef GREEN_MASK
  237.             #undef BLUE_MASK
  238.             #undef ALPHA_MASK
  239.         #undef RED_SHIFT
  240.         #undef GREEN_SHIFT
  241.         #undef BLUE_SHIFT
  242.         #undef ALPHA_SHIFT
  243.             break;
  244.     case GL_UNSIGNED_SHORT_5_5_5_1_EXT:
  245.             #define TYPE GLushort
  246.             #define RED_MASK   0xf800
  247.             #define GREEN_MASK 0x07c0
  248.             #define BLUE_MASK  0x003e
  249.             #define ALPHA_MASK 0x0001
  250.         #define RED_SHIFT   16
  251.         #define GREEN_SHIFT 21
  252.         #define BLUE_SHIFT  26
  253.         #define ALPHA_SHIFT 31
  254.             #include "ImgPack.c"
  255.             #undef TYPE
  256.             #undef RED_MASK
  257.             #undef GREEN_MASK
  258.             #undef BLUE_MASK
  259.             #undef ALPHA_MASK
  260.         #undef RED_SHIFT
  261.         #undef GREEN_SHIFT
  262.         #undef BLUE_SHIFT
  263.         #undef ALPHA_SHIFT
  264.             break;
  265.     case GL_UNSIGNED_INT_8_8_8_8_EXT:
  266.             #define TYPE GLuint
  267.             #define RED_MASK   0xff000000
  268.             #define GREEN_MASK 0x00ff0000
  269.             #define BLUE_MASK  0x0000ff00
  270.             #define ALPHA_MASK 0x000000ff
  271.         #define RED_SHIFT   0
  272.         #define GREEN_SHIFT 8
  273.         #define BLUE_SHIFT  16
  274.         #define ALPHA_SHIFT 24
  275.             #include "ImgPack.c"
  276.             #undef TYPE
  277.             #undef RED_MASK
  278.             #undef GREEN_MASK
  279.             #undef BLUE_MASK
  280.             #undef ALPHA_MASK
  281.         #undef RED_SHIFT
  282.         #undef GREEN_SHIFT
  283.         #undef BLUE_SHIFT
  284.         #undef ALPHA_SHIFT
  285.             break;
  286.     case GL_UNSIGNED_INT_10_10_10_2_EXT:
  287.             #define TYPE GLuint
  288.             #define RED_MASK   0xffc00000
  289.             #define GREEN_MASK 0x003ff000
  290.             #define BLUE_MASK  0x00000ffc
  291.             #define ALPHA_MASK 0x00000003
  292.         #define RED_SHIFT   0
  293.         #define GREEN_SHIFT 10
  294.         #define BLUE_SHIFT  20
  295.         #define ALPHA_SHIFT 30
  296.             #include "ImgPack.c"
  297.             #undef TYPE
  298.             #undef RED_MASK
  299.             #undef GREEN_MASK
  300.             #undef BLUE_MASK
  301.             #undef ALPHA_MASK
  302.         #undef RED_SHIFT
  303.         #undef GREEN_SHIFT
  304.         #undef BLUE_SHIFT
  305.         #undef ALPHA_SHIFT
  306.             break;
  307. #endif
  308.     }
  309.     *size = imageSize;
  310.     return (void*)image;
  311. }
  312.  
  313. static int IsPrime(int n)
  314. {
  315.     int i;
  316.     for (i = n/2; i > 1; i--) 
  317.         if (n % i == 0) return 0;
  318.     return 1;
  319. }
  320.  
  321. /* As the data created by this routine may be traversed, it will be allocated
  322.  * by the AlignMalloc routine and must be freed by the caller using AlignFree.
  323.  *
  324.  * If *numDrawn is 0 at calling time, this routine will figure a new value
  325.  * for that variable and set it, otherwise it will use that value.
  326.  */
  327. GLint* CreateSubImageData(int imageWidth, int imageHeight, int subWidth, int subHeight,
  328.                           float acceptObjs, float rejectObjs, float clipObjs,
  329.                           int clipMode, float percentClip, 
  330.               int spacedDraw,
  331.               int memAlignment,
  332.                           int* numDrawn)
  333. {
  334.     int m, n;
  335.     GLint *dataPtr;
  336.     int accept, reject, clip;
  337.     int x, y;
  338.     int i;
  339.     float dx, dy;
  340.     GLint *ptr;
  341.     int clipx, clipy;
  342.     int rejectx, rejecty;
  343.     int stride;
  344.     int index;
  345.  
  346.     if (*numDrawn == 0) {
  347.     m = (int)ceil( (float)imageWidth/(float)subWidth);
  348.     n = (int)ceil((float)imageHeight/(float)subHeight);
  349.     *numDrawn = m * n;
  350.     } else {
  351.     m = n = (int)ceil(sqrt(*numDrawn));
  352.     }
  353.  
  354.     dataPtr = (GLint*)AlignMalloc(sizeof(GLint) * 2 * *numDrawn, memAlignment);
  355.     ptr = dataPtr;
  356.  
  357.     accept = acceptObjs * (float)(*numDrawn);
  358.     reject = rejectObjs * (float)(*numDrawn);
  359.     clip = clipObjs * (float)(*numDrawn);
  360.     accept += *numDrawn - accept - reject - clip;
  361.  
  362.     /* Do clipped ones first, if any */
  363.     switch (clipMode) {
  364.     case Horizontal:
  365.         dx = (clip == 1) ? 0. : (float)(imageWidth - subWidth) / (float)(clip - 1);
  366.         /* figure y position of subimages for accurate percentClip */
  367.         y = imageHeight - (int)floor((1. - percentClip) * (float)subHeight + .5);
  368.         for (i = 0; i < clip; i++) {
  369.         *ptr++ = (GLint)floor((float)i * dx + .5);
  370.         *ptr++ = y;
  371.         }
  372.         break;
  373.     case Vertical:
  374.         dy = (clip == 1) ? 0. : (float)(imageHeight - subHeight) / (float)(clip - 1);
  375.         /* figure x position of subimages for accurate percentClip */
  376.         x = imageWidth - (int)floor((1. - percentClip) * (float)subWidth + .5);
  377.         for (i = 0; i < clip; i++) {
  378.         *ptr++ = x;
  379.         *ptr++ = (GLint)floor((float)i * dy + .5);
  380.         }
  381.         break;
  382.     case Random:
  383.         clipx = clip/2;
  384.         clipy = clip - clipx;
  385.         dx = (clipx == 1) ? 0. : (float)(imageWidth - subWidth) / (float)(clipx - 1);
  386.         dy = (clipy == 1) ? 0. : (float)(imageHeight - subHeight) / (float)(clipy - 1);
  387.         /* figure x,y positions of subimages for accurate percentClip */
  388.         x = imageWidth - (int)floor((1. - percentClip) * (float)subWidth + .5);
  389.         y = imageHeight - (int)floor((1. - percentClip) * (float)subHeight + .5);
  390.         for (i = 0; i < clipx; i++) {
  391.         *ptr++ = x;
  392.         *ptr++ = (GLint)floor((float)i * dy + .5);
  393.         }
  394.         for (i = 0; i < clipy; i++) {
  395.         *ptr++ = (GLint)floor((float)i * dx + .5);
  396.         *ptr++ = y;
  397.         }
  398.         break;
  399.     }
  400.  
  401.     /* Then do rejected ones */
  402.     rejectx = reject/2;
  403.     rejecty = reject - rejectx;
  404.     dx = (rejectx == 1) ? 0. : (float)(imageWidth - subWidth) / (float)(rejectx - 1);
  405.     dy = (rejecty == 1) ? 0. : (float)(imageHeight - subHeight) / (float)(rejecty - 1);
  406.     /* figure x,y positions of subimages to make sure they're rejected */
  407.     x = -5;
  408.     y = -5;
  409.     for (i = 0; i < rejectx; i++) {
  410.     *ptr++ = x;
  411.     *ptr++ = (GLint)floor((float)i * dy + .5);
  412.     }
  413.     for (i = 0; i < rejecty; i++) {
  414.     *ptr++ = (GLint)floor((float)i * dx + .5);
  415.     *ptr++ = y;
  416.     }
  417.  
  418.     /* Finally, do the accepted ones */
  419.     dx = (m == 1) ? 0. : (float)(imageWidth - subWidth) / (float)(m - 1);
  420.     dy = (n == 1) ? 0. : (float)(imageHeight - subHeight) / (float)(n - 1);
  421.     if (spacedDraw) {
  422.     /* Look for a prime number which is not a factor of "accept" */
  423.     /* This will become our "stride" to screw up the cache       */
  424.     for (i = accept/2; i > 1; i--) 
  425.         if (accept % i && IsPrime(i)) break;
  426.     /* Turn off stride if couldn't find a non-factor (e.g. accept = 2) */
  427.     if (i == 1) 
  428.         spacedDraw = 0;
  429.     else
  430.         stride = i;
  431.     }
  432.     for (i = 0; i < accept; i++) {
  433.     index = spacedDraw ? (i*stride%accept) : i;
  434.     *ptr++ = (GLint)floor((float)(index%m) * dx + .5);
  435.     *ptr++ = (GLint)floor((float)(index/m) * dy + .5);
  436.     }
  437.  
  438.     return dataPtr;
  439. }
  440.  
  441. void Image__DrawSomething(int rgba, int indexSize, int Double_Buffer)
  442. {
  443.     /*
  444.      * We don't know what the OpenGL state is at this point, so we're gonna have to 
  445.      * "start from scratch" to make sure that all the state is set so we actually 
  446.      * see something.
  447.      */
  448.     glPushAttrib(GL_COLOR_BUFFER_BIT | GL_ENABLE_BIT | GL_POLYGON_BIT);
  449.     glDisable(GL_LIGHTING);
  450.     glDisable(GL_CULL_FACE);
  451.     glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
  452.     glDisable(GL_POLYGON_STIPPLE);
  453.     glDisable(GL_TEXTURE_1D);
  454.     glDisable(GL_TEXTURE_2D);
  455.     glDisable(GL_FOG);
  456.     glDisable(GL_ALPHA_TEST);
  457.     glDisable(GL_STENCIL_TEST);
  458.     glDisable(GL_DEPTH_TEST);
  459.     glDisable(GL_BLEND);
  460.     glDisable(GL_SCISSOR_TEST);
  461.     glEnable(GL_DITHER);
  462.     if(Double_Buffer)
  463.       glDrawBuffer(GL_FRONT_AND_BACK);
  464.     else
  465.       glDrawBuffer(GL_FRONT);
  466.     glColorMask(GL_TRUE , GL_TRUE , GL_TRUE , GL_TRUE );
  467.     glIndexMask(0xffff);
  468.  
  469.     glBegin(GL_QUADS);
  470.     if (!rgba) {
  471.         int maxIndex = (1 << indexSize) - 1;
  472.         glIndexf(maxIndex);
  473.         glVertex3f(-1., -1., -1.);
  474.         glIndexf(0);
  475.         glVertex3f( 1., -1., -1.);
  476.         glIndexf(maxIndex);
  477.         glVertex3f( 1.,  1., -1.);
  478.         glIndexf(0);
  479.         glVertex3f(-1.,  1., -1.);
  480.     } else {
  481.         glColor4f(1., 0., 0., 0.);
  482.         glVertex3f(-1., -1., -1.);
  483.         glColor4f(0., 0., 1., 1.);
  484.         glVertex3f( 1., -1., -1.);
  485.         glColor4f(1., 1., 1., 0.);
  486.         glVertex3f( 1.,  1., -1.);
  487.         glColor4f(0., 1., 0., 1.);
  488.         glVertex3f(-1.,  1., -1.);
  489.     }
  490.     glEnd();
  491.  
  492.     if(Double_Buffer)
  493.       auxSwapBuffers();
  494.  
  495.     glPopAttrib();
  496. }
  497.  
  498. void* MakeTexImage(int imageWidth, int imageHeight, int imageDepth, int imageExtent,
  499.                     int imageFormat, int imageType, 
  500.             int imageAlignment, int imageSwapBytes, int imageLSBFirst,
  501.                     int memAlignment, int *imageSize)
  502. {
  503.     /* Since I haven't written a 3d or 4d image generator, we'll take the 2D image
  504.      * we get and replicate it numCopies times to get our multi-dimensional image */ 
  505.     int numCopies = 1;
  506.     int i;
  507.     void* image;
  508.  
  509.     numCopies *= imageDepth;
  510.     numCopies *= imageExtent;
  511.  
  512.     /* Figure our 2D texture image */
  513.     image = new_ImageData(
  514.                          imageWidth,
  515.              imageHeight,
  516.              imageFormat,
  517.              imageType,
  518.              imageAlignment,
  519.              imageSwapBytes,
  520.              imageLSBFirst,
  521.              memAlignment,
  522.              imageSize);
  523.  
  524.     /* Replicate to create multidimensional image, if needed */
  525.     if (numCopies > 1) {
  526.     char* multiImage = (char*)AlignMalloc(*imageSize * numCopies, memAlignment);
  527.     char* copy = multiImage;
  528.     for (i = 0; i < numCopies; i++) {
  529.         memcpy(copy, image, *imageSize);
  530.         copy += *imageSize;
  531.     }
  532.     AlignFree(image);
  533.     image = multiImage;
  534.     *imageSize *= numCopies;
  535.     }
  536.     return image;
  537. }
  538.